package com.warybee.mqspring.config;/**
 * All rights Reserved, Designed By warybee
 *
 * @description:
 * @author: jeebee
 */

import com.rabbitmq.client.Channel;
import com.warybee.mqspring.adapter.MessageDelegate;
import com.warybee.mqspring.convert.TextMessageConvert;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.support.ConsumerTagStrategy;
import org.springframework.amqp.support.converter.DefaultJackson2JavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 *@Description TODO
 *@author jeebee
 */
@Component
public class RabbitMQConfig {


      @Bean
      public ConnectionFactory connectionFactory(){
          CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
          connectionFactory.setAddresses("127.0.0.1:5672");
          connectionFactory.setUsername("guest");
          connectionFactory.setPassword("guest");
          connectionFactory.setVirtualHost("/");
          return connectionFactory;
      }

    /**
     * RabbitAdmin 注入
     * @param connectionFactory
     * @return
     */
    @Bean
      public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
          RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
          rabbitAdmin.setAutoStartup(true);
          return rabbitAdmin;
      }

    /**
     * RabbitTemplate
     * @param connectionFactory
     * @return
     */
    @Bean
      public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
          RabbitTemplate rabbitTemplate=new RabbitTemplate(connectionFactory);
          return rabbitTemplate;
      }

    /**
     * 消息监听
     * @param connectionFactory
     * @return
     */
      @Bean
      public SimpleMessageListenerContainer simpleMessageListenerContainer(ConnectionFactory connectionFactory){
        SimpleMessageListenerContainer container=new SimpleMessageListenerContainer(connectionFactory);
        //监听的消息队列，可以设置多个
        container.setQueues(queue001(),queue002());
        //消息签收模式
        container.setAcknowledgeMode(AcknowledgeMode.AUTO);
        container.setConcurrentConsumers(1);//当前消费者数量
        container.setMaxConcurrentConsumers(5);//最大消费者数量
        container.setDefaultRequeueRejected(false);//消息失败，是否重回队列
        //设置消费者的Tag唯一标识，AMQP封装了可以根据Tag进行消息的消费
        container.setConsumerTagStrategy(new ConsumerTagStrategy() {
            @Override
            public String createConsumerTag(String s) {
                return s+"_"+ UUID.randomUUID().toString();
            }
        });

        /**************************接收消息方式****************************/

        /**
         * 接收消息方式1
         */
        /*container.setMessageListener(new ChannelAwareMessageListener(){

            *//**
             * 接受消息
             * @param message
             * @param channel
             * @throws Exception
             *//*
            @Override
            public void onMessage(Message message, Channel channel) throws Exception {
                System.out.println("-------------消费者接收消息："+new String(message.getBody()));
            }
        });*/

        /**
         * 接收消息方式2
          */


        MessageListenerAdapter adapter=new MessageListenerAdapter(new MessageDelegate());
        //adapter.setDefaultListenerMethod("customerMethod"); //可以修改消息委托类中的默认方法
        adapter.setMessageConverter(new TextMessageConvert());
        container.setMessageListener(adapter);


        /**
         * 根据队列绑定方法 接收消息方式3
         */
       /* MessageListenerAdapter adapter=new MessageListenerAdapter(new MessageDelegate());
        Map<String, String> queueOrTagToMethodName = new HashMap<String, String>();
        queueOrTagToMethodName.put("queue001","method1");
        queueOrTagToMethodName.put("queue002","method2");
        adapter.setQueueOrTagToMethodName(queueOrTagToMethodName);
        adapter.setMessageConverter(new TextMessageConvert());
        container.setMessageListener(adapter);*/

        /****************************接收消息方式 end**************************/

        /****************************消息类型转化方式 **************************/

        /**
         * JSON 方式 转化为Map
         */
       /*
         MessageListenerAdapter adapter=new MessageListenerAdapter(new MessageDelegate());
        Jackson2JsonMessageConverter jackson2JsonMessageConverter=new Jackson2JsonMessageConverter();
        adapter.setMessageConverter(jackson2JsonMessageConverter);
        container.setMessageListener(adapter);
        */


        /**
         * JSON 方式 转化为Java对象
         */
        /*MessageListenerAdapter adapter=new MessageListenerAdapter(new MessageDelegate());
        Jackson2JsonMessageConverter jackson2JsonMessageConverter=new Jackson2JsonMessageConverter();

        DefaultJackson2JavaTypeMapper javaTypeMapper=new DefaultJackson2JavaTypeMapper();
        //添加信任包名称，不然会转化失败
        javaTypeMapper.setTrustedPackages("com.warybee.mqspring.entity");

        jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);

        adapter.setMessageConverter(jackson2JsonMessageConverter);
        container.setMessageListener(adapter);*/


        /**
         * 多对象映射
         */
       /* MessageListenerAdapter adapter=new MessageListenerAdapter(new MessageDelegate());
        Jackson2JsonMessageConverter jackson2JsonMessageConverter=new Jackson2JsonMessageConverter();

        DefaultJackson2JavaTypeMapper javaTypeMapper=new DefaultJackson2JavaTypeMapper();
        //添加信任包名称，不然会转化失败
        javaTypeMapper.setTrustedPackages("com.warybee.mqspring.entity");

        Map<String,Class<?>> idClassMapping=new HashMap<>();
        idClassMapping.put("order",com.warybee.mqspring.entity.Order.class);
        idClassMapping.put("user",com.warybee.mqspring.entity.User.class);
        javaTypeMapper.setIdClassMapping(idClassMapping);//多对象映射

        jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);

        adapter.setMessageConverter(jackson2JsonMessageConverter);
        container.setMessageListener(adapter);*/


        /****************************消息类型转化方式end**************************/

        return container;
      }

      @Bean
      public TopicExchange topicExchange001(){
          return new TopicExchange("topicExchange001",true,false);
      }

      @Bean
      public Queue queue001(){
        return new Queue("queue001",true,false,false);
      }

      @Bean
      public Binding binding001(){
          return BindingBuilder.bind(queue001()).to(topicExchange001()).with("spring.#");
      }

      @Bean
      public Queue queue002(){
          return new Queue("queue002",true);
      }

      @Bean
      public Binding binding002(){
          return BindingBuilder.bind(queue002()).to(topicExchange001()).with("springboot.#");
      }
}
